package edu.hawaii.teams.halealohacli.command;

import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;

/**
 * Finds the energy consumption for a given source since a given date.
 * 
 * @author Branden Ogata
 * 
 */
public class EnergySince implements Command {

  /**
   * Returns the energy consumption for a source since a given date. This is determined through
   * finding the energy that the source has consumed from the given date to the present.
   * 
   * @param client A WattDepotClient to find the source in.
   * @param details String instances identifying the source and date to examine.
   * @return data A String containing the energy that the source has consumed since given date. If
   * multiple data exist, places each on a new line.
   * @throws Exception Handles any problems that may occur.
   * 
   */
  @Override
  public String getData(WattDepotClient client, String... details) throws Exception {
    // Constant double used to convert from watt to kilowatt.
    final double KILO = 1000.0;
    StringBuilder buffer = new StringBuilder();
    String currentSource = null;
    String givenDate = null;

    for (String text : details) {
      // If currentSource is null, then this String is a source
      if (currentSource == null) {
        currentSource = text;
      }
      // Else if givenDate is null, then this String is a date
      else if (givenDate == null) {
        givenDate = text;
      }

      // If both currentSource and givenDate are defined
      if ((currentSource != null) && (givenDate != null)) {
        try {
          // Parse givenDate
          int year = Utility.getDate(givenDate, "year");
          int month = Utility.getDate(givenDate, "month");
          int day = Utility.getDate(givenDate, "day");

          // Create XMLGregorianCalendar instances to represent beginning and end of givenDate
          XMLGregorianCalendar startDate = client.getLatestSensorData(currentSource).getTimestamp();
          XMLGregorianCalendar endDate = client.getLatestSensorData(currentSource).getTimestamp();

          startDate.setYear(year);
          startDate.setMonth(month);
          startDate.setDay(day);
          startDate.setHour(0);
          startDate.setMinute(0);
          startDate.setSecond(0);
          startDate.setMillisecond(0);

          // Get energy consumed through client
          buffer.append(client.getEnergyConsumed(currentSource, startDate, endDate, 0) / KILO
              + "\n");
        }
        catch (NumberFormatException e) {
          buffer.append("Error: An error occurred while parsing the date.\n\n");
        }
        catch (StringIndexOutOfBoundsException e) {
          buffer.append("Error: An error occurred while parsing the date; "
              + "the formatting is incorrect.\n\n");
        }
        catch (IllegalArgumentException e) {
          buffer.append("Error: An error occurred in using the XMLGregorianCalendar class.\n\n");
        }
        catch (BadXmlException e) {
          buffer.append("Error: An error occurred in the XML from the server.\n\n");
        }
        catch (MiscClientException e) {
          buffer.append("Error: An error occurred while retrieving data.\n\n");
        }
        catch (ResourceNotFoundException e) {
          buffer.append("Error: The source " + currentSource + " could not be found.\n\n");
        }

        // Reset currentSource and givenDate to null
        currentSource = null;
        givenDate = null;
      }
    }
    return buffer.toString();
  }
}